<?php

namespace Gnway\Ticket\Rest\Annotation\Parser;

use Gnway\Ticket\Rest\Annotation\Resource;
use ReflectionClass;
use ReflectionException;
use ReflectionNamedType;
use RuntimeException;

/**
 * Class ResourceParser
 */
class ResourceParser extends AbstractParser
{

  /**
   * Class Annotations
   *
   * @var array
   */
  private array $classAnnotation;

  /**
   * ResourceParser constructor.
   *
   * @param array $classAnnotation
   * @throws ReflectionException
   */
  public function __construct(array $classAnnotation)
  {
    parent::__construct();

    $this->classAnnotation = $classAnnotation;
  }

  /**
   * Parser Class Resource
   *
   * @return array
   */
  public function parse(): array
  {
    $resources = [];

    foreach ($this->classAnnotation as $class) {
      if ( ! (($class->annotation !== NULL) && ($class->reflection instanceof ReflectionClass))) {
        continue;
      }

      foreach ($class->reflection->getProperties() as $property) {
        $inject = $this->reader->getPropertyAnnotation($property, Resource::class);
        if ( ! ($inject instanceof Resource)) {
          continue;
        }
        $resource = $inject->getName();
        if ($resource === '' && ($type = $property->getType()) instanceof ReflectionNamedType) {
          $name = $type->getName();
          class_exists($name) && $resource = $name;
        }
        if (!class_exists($resource)) {
          throw new RuntimeException(sprintf('Attribute "name" of @Resource declared on property %s::$%s must be a class',
            $class->reflection->getName(), $property->getName()));
        }

        $resources[$class->reflection->getName()][$property->getName()] = $resource;
      }
    }

    return $resources;
  }
}